package com.bj58.mis.apm.server.kylin.common.util;

import java.io.Serializable;
import java.nio.ByteBuffer;

public class ByteArray implements Comparable<ByteArray>, Serializable {
    private static final long serialVersionUID = 1L;
    private byte[] data;
    private int offset;
    private int length;

    public static ByteArray allocate(int length) {
        return new ByteArray(new byte[length]);
    }

    public static ByteArray copyOf(byte[] array, int offset, int length) {
        byte[] space = new byte[length];
        System.arraycopy(array, offset, space, 0, length);
        return new ByteArray(space, 0, length);
    }

    public ByteArray() {
        this((byte[])null, 0, 0);
    }

    public ByteArray(int capacity) {
        this(new byte[capacity], 0, capacity);
    }

    public ByteArray(byte[] data) {
        this(data, 0, data == null ? 0 : data.length);
    }

    public ByteArray(byte[] data, int offset, int length) {
        this.data = data;
        this.offset = offset;
        this.length = length;
    }

    public byte[] array() {
        return this.data;
    }

    public int offset() {
        return this.offset;
    }

    public int length() {
        return this.length;
    }

    public void exportData(ByteBuffer out) {
        BytesUtil.writeByteArray(this.data, this.offset, this.length, out);
    }

    public static ByteArray importData(ByteBuffer in) {
        byte[] bytes = BytesUtil.readByteArray(in);
        return new ByteArray(bytes);
    }

    public ByteBuffer asBuffer() {
        if (this.data == null) {
            return null;
        } else {
            return this.offset == 0 && this.length == this.data.length ? ByteBuffer.wrap(this.data) : ByteBuffer.wrap(this.data, this.offset, this.length).slice();
        }
    }

    public byte[] toBytes() {
        return Bytes.copy(this.array(), this.offset(), this.length());
    }

    public void setLength(int pos) {
        this.length = pos;
    }

    public void reset(byte[] data, int offset, int len) {
        this.data = data;
        this.offset = offset;
        this.length = len;
    }

    public byte get(int i) {
        return this.data[this.offset + i];
    }

    public int hashCode() {
        if (this.data == null) {
            return 0;
        } else if (this.length <= 8 && this.length > 0) {
            long value = BytesUtil.readLong(this.data, this.offset, this.length);
            return (int)(value ^ value >>> 32);
        } else {
            return Bytes.hashCode(this.data, this.offset, this.length);
        }
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (obj == null) {
            return false;
        } else if (this.getClass() != obj.getClass()) {
            return false;
        } else {
            ByteArray o = (ByteArray)obj;
            if (this.data == null && o.data == null) {
                return true;
            } else {
                return this.data != null && o.data != null ? Bytes.equals(this.data, this.offset, this.length, o.data, o.offset, o.length) : false;
            }
        }
    }

    public int compareTo(ByteArray o) {
        if (this.data == null && o.data == null) {
            return 0;
        } else if (this.data == null) {
            return -1;
        } else {
            return o.data == null ? 1 : Bytes.compareTo(this.data, this.offset, this.length, o.data, o.offset, o.length);
        }
    }

    public String toReadableText() {
        return this.data == null ? null : BytesUtil.toHex(this.data, this.offset, this.length);
    }

    public String toString() {
        return this.data == null ? null : Bytes.toStringBinary(this.data, this.offset, this.length);
    }
}
